package com.atguigu.bookcity.service.impl;

import com.atguigu.bookcity.entity.BookPurchaseApply;
import com.atguigu.bookcity.entity.vo.BookPurchaseVo;
import com.atguigu.bookcity.mapper.BookPurchaseApplyMapper;
import com.atguigu.bookcity.mapper.RoleMapper;
import com.atguigu.bookcity.mapper.UserMapper;
import com.atguigu.bookcity.mapper.UserRoleMapper;
import com.atguigu.bookcity.service.BookPurchaseApplyService;
import com.atguigu.bookcity.status.ApplyEnum;
import com.atguigu.bookcity.utils.PageUtils;
import com.atguigu.bookcity.utils.Query;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;

/*
 * <p>
 *  服务实现类
 * </p>
 *
 * @author zsc
 * @since 2021-05-31
 */

/**
 * @author ws
 * @since 2021-05-31
 */
@Slf4j
@SuppressWarnings("all")
@Service("bookPurchaseApplyService")
public class BookPurchaseApplyServiceImpl extends ServiceImpl<BookPurchaseApplyMapper, BookPurchaseApply> implements BookPurchaseApplyService {

    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private TaskService taskService;

    @Autowired
    private RepositoryService repositoryService;

    @Autowired
    private HistoryService historyService;

    @Resource
    private UserRoleMapper userRoleMapper;

    @Resource
    private UserMapper userMapper;

    @Resource
    private RoleMapper roleMapper;




    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<BookPurchaseApply> page = this.page(
                new Query<BookPurchaseApply>().getPage(params),
                new QueryWrapper<BookPurchaseApply>()
        );
        return new PageUtils(page);
    }


    @Override
    public List<BookPurchaseApply> getMyTasks(String applicantId, Integer page, Integer limit) {
        List<BookPurchaseApply> bookPurchaseApplyList = new ArrayList<>();

        //根据用户查询任务
        List<Integer> applyIds = new ArrayList<>();
        List<Task> tasks = taskService.createTaskQuery().taskAssignee(applicantId).listPage((page - 1) * limit, limit);
        if (CollectionUtils.isEmpty(tasks))
            return null;

        //根据任务id查询存储的wareApplyId（在启动流程实例时存取）,封装为List<Integer>
        for (Task task : tasks) {
            BookPurchaseApply bookPurchaseApply = (BookPurchaseApply) taskService.getVariable(task.getId(), "bookPurchaseApply");
            bookPurchaseApplyList.add(bookPurchaseApply);
        }

        return bookPurchaseApplyList;
    }


    /**
     * 添加购书申请
     */

    @Override
    public boolean addApply(BookPurchaseVo bookPurchaseVo) {
        try {
            BookPurchaseApply bookPurchaseApply = new BookPurchaseApply();
            BeanUtils.copyProperties(bookPurchaseVo, bookPurchaseApply);
            //设置申请开始时间
            bookPurchaseApply.setApplyStartTime(new Date());

            this.save(bookPurchaseApply);

            //设置流程变量
            Map<String, Object> variables = new HashMap<String, Object>();
            //设置任务申请人
            variables.put(ApplyEnum.ASSIGNEE.getMessage(), bookPurchaseApply.getApplyId());
            //设置入库数量
            variables.put(ApplyEnum.BOOKNUMBER.getMessage(), bookPurchaseApply.getStock());
            //TODO 设置经理候选人与财务候选人
            //1.查询经理与财务的roleId
            String managerId = roleMapper.getRoleIdByName("manager");
            String financeId = roleMapper.getRoleIdByName("financial");
            //根据roleId查询userId
            String memberIdsOfmanager = userRoleMapper.getMemberIdsByRoleId(managerId);
            String memberIdsOfFinance = userRoleMapper.getMemberIdsByRoleId(financeId);
            //设置经理候选人
            variables.put(ApplyEnum.MANAGERS.getMessage(), memberIdsOfmanager);
            //设置财务候选人
            variables.put(ApplyEnum.FINANCIALS.getMessage(), memberIdsOfFinance);
            //设置wareApplyEnity
            bookPurchaseApply.setStatus(ApplyEnum.PENDING.getMessage());
            variables.put("bookPurchaseApply", bookPurchaseApply);

            //启动流程实例并获取流程实例Id processInstanceId
            String processInstanceId = null;

            ProcessInstance processInstance =
                    runtimeService
                            .startProcessInstanceByKey(
                                    ApplyEnum.PROCESSDEFINITIONKEY.getMessage(),
                                    bookPurchaseApply.getApplyId()
                                    , variables
                                    );
            processInstanceId = processInstance.getProcessInstanceId();


            //申请者提交申请
            String taskId = taskService
                    .createTaskQuery()
                    .processInstanceId(processInstanceId)
                    .singleResult()
                    .getId();
            taskService.complete(taskId);
            log.info("提交申请成功！");

            //更新bookPurchaseApply
            this.updateById(bookPurchaseApply);
        } catch (BeansException e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    @Override
    public List<BookPurchaseApply> getCandidateTasks(String userId, Integer page, Integer limit) {
        List<BookPurchaseApply> bookPurchaseApplyList = new ArrayList<>();

        //根据用户查询任务
        List<Integer> bookPurchaseApplyIds = new ArrayList<>();
        List<Task> tasks = taskService.createTaskQuery().taskCandidateUser(userId).listPage((page - 1) * limit, limit);
        if (CollectionUtils.isEmpty(tasks))
            return null;

        //根据任务id查询存储的wareApplyId（在启动流程实例时存取）,封装为List<Integer>
        for (Task task : tasks) {
            BookPurchaseApply bookPurchaseApply = (BookPurchaseApply) taskService.getVariable(task.getId(), "wareApplyEntity");
            bookPurchaseApplyList.add(bookPurchaseApply);
        }

        return bookPurchaseApplyList;
    }

    //通过申请人id获取我的申请
    @Override
    public List<BookPurchaseApply> getByUserId(String userId) {
        List<BookPurchaseApply> bookPurchaseApplies = this.list(new QueryWrapper<BookPurchaseApply>().eq("applicant_id", userId));
        return bookPurchaseApplies;
    }

}
